package com.itheima.d2_pool;

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;

//目标：掌握使用使用Executors工具类实现线程池
public class Demo03 {
    public static void main(String[] args) {
        /**
         * newFixedThreadPool(int nThreads)：
         *      创建固定线程数量的线程池，如果某个线程因为执行异常而结束，那么线程池会补充一个新线程替代它
                可能大量任务堆积
         * newSingleThreadExecutor()：
         *      创建只有一个线程的线程池对象，如果该线程出现异常而结束，那么线程池会补充一个新线程
         *      可能大量任务堆积
         * newCachedThreadPool()：
         *      线程数量随着任务增加而增加，如果线程任务执行完毕且空闲了60s则会被回收掉
         *      可能导致大量线程堆积
         * newScheduledThreadPool(int corePoolSize)：
         *      创建一个线程池，可以实现在给定的延迟后运行任务，或者定期执行任务
         *      
         */
        //需求1
        //one();

        //需求2
        //two();

        //需求3
        //three();

        //four();
    }

    public static void four() {
        /**
         * 需求4：
         *      使用newScheduledThreadPool(int corePoolSize)获取线程池，指定2个核心线程
         *      执行1个任务，延时1s，间隔2s执行
         *      任务中打印线程名字和任务的数字
         */
        ScheduledExecutorService pool = Executors.newScheduledThreadPool(2);

        pool.scheduleWithFixedDelay(
                //要执行的任务
                new Runnable() {
                    @Override
                    public void run() {
                        System.out.println("任务...");
                    }
                },
                //延迟多少时间后开始执行
                1,
                //间隔多少时间执行
                3,
                //时间单位
                TimeUnit.SECONDS);

    }

    public static void three() {
        /**
         * 需求3：
         *      使用newCachedThreadPool()获取线程池
         *      执行1、2、3、4、5个任务，任务中打印线程名字和任务的数字
         */
        ExecutorService pool = Executors.newCachedThreadPool();
        for (int i = 1; i <= 5; i++) {
            pool.execute(new MyRunnable(i));
        }
        pool.shutdown();
    }

    public static void two() {
        /**
         * 需求2：
         *      使用newSingleThreadExecutor()获取线程池
         *      执行10个任务，任务中打印线程名字和任务的数字
         *      在第3个任务的时候，使任务出现一个异常
         */
        ExecutorService pool = Executors.newSingleThreadExecutor();
        for (int i = 1; i <= 10; i++) {
            pool.execute(new MyRunnable(i));
        }
        pool.shutdown();
    }

    public static void one() {
        /**
         * 需求1：
         *      使用newFixedThreadPool(int nThreads)获取线程池，指定线程数量3
         *      执行30个任务，任务中打印线程名字和任务的数字
         *      在第2个任务的时候，使任务出现一个异常
         */
        ExecutorService pool = Executors.newFixedThreadPool(3);

        for (int i = 1; i <= 30; i++) {
            pool.execute(new MyRunnable(i));
        }

        pool.shutdown();
    }
}

